package com.hsgene.gateway.support;

import com.hsgene.common.ClientType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * ClientRequestValidation权限验证Listener
 * 当Spring Bean初始化完成后，自动搜索实现了ClientRequestValidation接口的实现类
 *
 * @author wangbing
 * @version 1.0, 2018/11/9
 */
@Component
public class ClientRequestValidationListener implements ApplicationListener<ContextRefreshedEvent> {

    private final static Logger LOGGER = LoggerFactory.getLogger(ClientRequestValidationListener.class);

    @Resource
    private ClientRequestValidationSupport validationSupport;

    /**
     * resource = org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
     * ApplicationContext = org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
     * 当事件条件满足上述要求时可以取到ClientRequestFilter相关的Bean，其它情况测试无法获取
     *
     * @param event 事件源
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (event.getApplicationContext() instanceof AnnotationConfigServletWebServerApplicationContext) {
            LOGGER.info("=====刷新客户端请求过滤链=====");
            LOGGER.info("=====ContextRefreshedEvent=====" + event.getSource().getClass().getName());
            LOGGER.info("=====ApplicationContext=====" + event.getApplicationContext().getClass().getName());
            Map<String, ClientRequestFilter> filterMap = event.getApplicationContext().getBeansOfType(ClientRequestFilter.class);
            filterMap.forEach((name, bean) -> {
                LOGGER.info("过滤器名称：{}，[{}]", name, bean == null ? "null" : bean.getClass().getName());
            });
            Map<ClientType, List<ClientRequestFilter>> map = filterMap.values().stream()
                    .sorted(Comparator.comparingInt(ClientRequestFilter::filterOrder))
                    .collect(Collectors.groupingBy(ClientRequestFilter::filterType));
            validationSupport.setFilterMap(map);
        }
    }
}
